package com.hmeter.mongodb;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.MongoClient;

public class MongoDbUtility {
	
	private String dbName = null;
	private String collectionName = null;
	private MongoClient mongo = null;
	private DB mongoDb = null;
	private DBCollection mongoDbCollection = null;
			
	public MongoDbUtility(String host, int port, String dbName, String collectionName) throws UnknownHostException
	{
		this.dbName = dbName;
		this.collectionName = collectionName;
		this.initConnection(host, port);
	}
	
	public DBCollection getMongoDbCollection() {
		return mongoDbCollection;
	}

	public void setMongoDbCollection(DBCollection mongoDbCollection) {
		this.mongoDbCollection = mongoDbCollection;
	}
	
	public void initConnection(String host, int port) throws UnknownHostException
	{
		mongo = new MongoClient(host, port);
		mongoDb = mongo.getDB(dbName);
		mongoDbCollection = mongoDb.getCollection(collectionName);
	}
	
	public Map<String, Object> parseInputContent(String inputContent, String delimiter)
	{
		Map<String, Object> parsedContent = new HashMap<String, Object>();
		String[] contentSplit = inputContent.split(delimiter);
		
		for (String content : contentSplit)
		{
			String[] cntSplit = content.split(":");
			
			if (this.isNumber(cntSplit[1]))	
			{
				parsedContent.put(cntSplit[0], Integer.parseInt(cntSplit[1]));
			} 
			else if (this.isBoolean(cntSplit[1])) 
			{
				parsedContent.put(cntSplit[0], Boolean.parseBoolean(cntSplit[1]));
			}
			else
			{
				parsedContent.put(cntSplit[0], cntSplit[1]);
			}
		}	
		return parsedContent;
	}
	
	public BasicDBObject makeSimpleDocument(Map<String, Object> data)
	{
		BasicDBObject doc = new BasicDBObject();
		for (Map.Entry<String, Object> entry : data.entrySet())
		{
			doc.put(entry.getKey(), entry.getValue());
		}
		return doc;
	}
				
	public List<BasicDBObject> parseQueryInputContent(String inputContent, String delimiter)
	{
		List<BasicDBObject> objects = new ArrayList<BasicDBObject>();
		String[] contentSplit = inputContent.split(delimiter);
		
		for (String content : contentSplit)
		{
			String[] cnt = content.split("\\|.+\\|");
			String operator = content.replaceAll("(.+)\\|(.+)\\|(.+)", "$2");
			
			if (this.isNumber(cnt[1]))	
			{
				objects.add(this.makeSimpleQuery(cnt[0], Integer.parseInt(cnt[1]), operator));
			} 
			else if (this.isBoolean(cnt[1])) 
			{
				objects.add(this.makeSimpleQuery(cnt[0], Boolean.parseBoolean(cnt[1]), operator));
			}
			else
			{
				objects.add(this.makeSimpleQuery(cnt[0], cnt[1], operator));
			}
		}
		
		return objects;
	}
	
	public BasicDBObject makeSimpleQuery(String key, Object value, String operator)
	{
		BasicDBObject query = new BasicDBObject();
		if (operator.equals("$eq")) {
			query.put(key, value);
		}
		else {
			query.put(key, new BasicDBObject(operator, value));
		}
		return query;
	}
		
	public boolean isNumber(String value)
	{
		boolean isNumber = false;
		try 
		{
			Integer.parseInt(value);
			isNumber = true;
		}
		catch (NumberFormatException ex)
		{
			isNumber = false;
		}
		
		return isNumber;
	}
	
	public boolean isBoolean(String value)
	{
		boolean isBoolean = false;
		if (value.equals("true") || value.equals("false"))
		{
			isBoolean = true;
		}
		return isBoolean;
	}
}
